#ifndef ROBOTHELPER_H
#define ROBOTHELPER_H

#include "src/pubimp.h"
#include "device/robotmanager.h"
#include "src/Communication/UDPConnect/UDPHelper.h"
#include "tools.h"
#include <random>
#include <atomic>
#include <tuple>
//#include "algorithm/robot_move.h"
#include "src/Manager/ThreadPool.h"
#include "MU_API.h"
#include "MU_ExpMessage.h"
#include "src/Manager/TaskManager.h"
#include "src/define/func_define.h"
#include "base/errorcode.h"
#include "src/SoftWare/DateTime/DateTime.h"


namespace ROBOT {
    /// 定义通讯的类型
    typedef enum Tag_COM_TYPE
    {
        T_UDP = 0u,
        T_TCP
    }T_COM_TYPE;


}




class RobotHelper
{
public:

    static RobotHelper* GetInstance(){
        static QMutex mutex;
        static QScopedPointer<RobotHelper> inst;
        if (Q_UNLIKELY(!inst)) {
            mutex.lock();
            if (!inst) {
                inst.reset(new RobotHelper);
            }
            mutex.unlock();
        }
        return inst.data();
    }

    bool GetOpened() const{
        try{
            // bool ret = _robot->getStatus() == RUNNING;

            return true;
        }catch(...){
            qDebug()<<"......";
            return false;
        }
    }

    /**
     * @brief SelectRobot
     * @details 选择机器人
     */
    void SelectRobot(){
        try {
            Config config("etc/catch.info") ;
            _robot.selectRobot(static_cast<RobotType>(config.get<int>("robotType"))) ;
        } catch (...) {
            throw MU_EXPS::EXP_RBT_SYSCONF;
        }
    }

    /// 异步处理掉线事件
    void InstallOutlineEvent();

    /// 重新连接
    void ReConnect();

    /// 暂停运动
    /// arg1:is pause?
    /// true:pause  ,false:run
    void PauseMotion(bool state);

    /// 急停
    void CriticalStop(bool state);

    /// 相对运动
    void RelativeMove(RobotPos,int speed = 60);

    /// abs运动
    void ABSMove(RobotPos,int speed = 60);

    /// abs运动
    std::future<MU_RETURN_LIST> ABSMove(std::vector<RobotPos>,int speed = 60);

    /// abs运动AXis
    void ABSMoveAxis(RobotAxle,int speed = 60);

    // 送丝
    void OutSilk();

    // 收
    void InSilk();

    /// 连接到机器人
    void ConnectToRobot();

    /**
     * @brief ProcessContinousPos
     * @param 必须是相对点的增量，不能是绝对点
     * @param speed
     */
    void ProcessContinousPos(std::vector<RobotPos>,int speed = 100);

    void GetError();

    void CloseRobot();      // 断开机器人链接

    void handlerDis();      // 处理掉线问题

    void OpenWeld(weldInfo);

    void CloseWeld();

    void MoveToSafePos();       // 移动到默认的安全点，轴

    void RetractMove(RobotPos s,int len,int dy,int dx);         // 以回撤方式运动到某个点

    bool GetConEnd();           // 获取多点运动是否结束

public:
    RobotPos getCurrentPos();
    RobotManager _robot ;
    RobotPos     defaultPos;    // 安全点
    RobotAxle    defaultAxle;    // 安全轴

private:
    RobotHelper();
    Config _sys_config ;

    /// 配置
    std::atomic<bool> _allowMove = ATOMIC_FLAG_INIT;    /// 机器人的可移动状态
    std::deque<RobotPos> _threadHandle;              ///用于控制多点运动的队列
    std::atomic<bool> zeroLock = ATOMIC_FLAG_INIT;      ///用于控制多点运动的队列锁

    int  threshold = 0 ;    // 警告触发的阈值

    /// 线程同步锁
    mutable std::recursive_mutex _mtx ;

private:
    /// 私有方法，相对运动
    MU_RETURNS _relativeMove(RobotPos,int speed = 100);
    void _absMove(RobotPos,int speed = 100);
    MU_RETURNS _absMoveC(std::vector<RobotPos>,int speed = 100);
    void _absMoveAxis(RobotAxle,int speed = 100);
    /// 启动UDP链接
    void StartUDP();

    /// 读取UDP配置文件
    void ReadConfig();
    /// 初始化成员数据,线程
    void initMemberData();

    MU_RETURNS _connect();
};

#endif // ROBOTHELPER_H
